home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / System 7 / ChooserHack / ChooserHack.c next >
Text File  |  1993-06-16  |  20KB  |  708 lines

  1. /*
  2.     File:        ChooserHack.c
  3.  
  4.     Contains:    Code to maintain a directory hierarchy that maps to zones, file servers, and volumes
  5.  
  6.     Written by:    Nick Kledzik 
  7.  
  8.     Date:        June 93
  9.     
  10.     For:        MacHack 93
  11.  
  12. */
  13.  
  14.  
  15. #define SystemSevenOrLater 1
  16.  
  17. #include <StdDef.h>
  18. #include <Memory.h>
  19. #include <AppleTalk.h>
  20. #include <Folders.h>
  21. #include <Errors.h>
  22. #include <Files.h>
  23. #include <Resources.h>
  24. #include <Aliases.h>
  25.  
  26. // inlines that should have been in AppleTalk.h
  27. #pragma parameter __D0 GetZoneListSync(__A0)
  28. pascal OSErr GetZoneListSync(XPPParmBlkPtr paramBlock)
  29.  = {0x317C, 0x0006, 0x001C, 0x317C, 0xFFD7, 0x0018, 0x317C, 0x00F6, 0x001A, 0xA004}; 
  30.  
  31. #pragma parameter __D0 PLookupNameSync(__A0)
  32. pascal OSErr PLookupNameSync(MPPPBPtr paramBlock)
  33.  = {0x317C, 0x00FB, 0x001A, 0x317C, 0xFFF6, 0x0018, 0xA004}; 
  34.  
  35. #pragma parameter __D0 ASPGetStatusSync(__A0)
  36. pascal OSErr ASPGetStatusSync(XPPParmBlkPtr paramBlock)
  37.  = {0x317C, 0x00FB, 0x001A, 0xA004}; 
  38.  
  39. #pragma parameter __D0 AFPCommandSync(__A0)
  40. pascal OSErr AFPCommandSync(XPPParmBlkPtr paramBlock)
  41.  = {0x317C, 0x00FA, 0x001A, 0xA004}; 
  42.  
  43. // inline that should have been in Files.h
  44. #pragma parameter __D0 PBMountAFPVolSync(__A0)
  45. pascal OSErr PBMountAFPVolSync(ParmBlkPtr paramBlock)
  46.  = {0x7041,0xA260}; 
  47.  
  48.  
  49.  
  50. struct Globals 
  51. {
  52.     short    theNetworkVRefNum;
  53.     long    theNetworkFolderID;
  54. };
  55. typedef struct Globals  Globals;
  56.  
  57. extern Globals* GetGlobals();
  58. extern void InstallPatches();
  59.  
  60.  
  61. void SetCustomFolderIcon(short vRefNum, long dirID, short iconID)
  62. {
  63.     CInfoPBRec    cpb;
  64.     OSErr        err;
  65.     Handle    icl8;
  66.     Handle    icl4;
  67.     Handle    ICNP;
  68.     Handle    ics8;
  69.     Handle    ics4;
  70.     Handle    icsP;
  71.     short    ref;
  72.     Str32    netFolderName;
  73.     Str32    iconFilename;
  74.     
  75.     // get folder icon resources
  76.     icl8 = GetResource('icl8', iconID);
  77.     icl4 = GetResource('icl4', iconID);
  78.     ICNP = GetResource('ICN#', iconID);
  79.     ics8 = GetResource('ics8', iconID);
  80.     ics4 = GetResource('ics4', iconID);
  81.     icsP = GetResource('ics#', iconID);
  82.     DetachResource(icl8);
  83.     DetachResource(icl4);
  84.     DetachResource(ICNP);
  85.     DetachResource(ics8);
  86.     DetachResource(ics4);
  87.     DetachResource(icsP);
  88.     
  89.     // make icon file in folder and add resources
  90.     BlockMove("\pIcon\015", iconFilename, 6);
  91.     HCreateResFile(vRefNum, dirID, iconFilename);
  92.     ref = HOpenResFile(vRefNum, dirID, iconFilename, fsCurPerm); 
  93.     AddResource(icl8, 'icl8', -16455, "\p");
  94.     AddResource(icl4, 'icl4', -16455, "\p");
  95.     AddResource(ICNP, 'ICN#', -16455, "\p");
  96.     AddResource(ics8, 'ics8', -16455, "\p");
  97.     AddResource(ics4, 'ics4', -16455, "\p");
  98.     AddResource(icsP, 'ics#', -16455, "\p");
  99.     CloseResFile(ref);
  100.  
  101.     // make file invisible
  102.     cpb.hFileInfo.ioVRefNum = vRefNum;
  103.     cpb.hFileInfo.ioDirID = dirID;
  104.     cpb.hFileInfo.ioNamePtr = iconFilename;
  105.     cpb.hFileInfo.ioFDirIndex = 0;
  106.     cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  107.     err = PBGetCatInfoSync(&cpb);
  108.     if (err == noErr)
  109.     {
  110.         cpb.hFileInfo.ioVRefNum = vRefNum;
  111.         cpb.hFileInfo.ioDirID = dirID;
  112.         cpb.hFileInfo.ioNamePtr = iconFilename;
  113.         cpb.hFileInfo.ioFDirIndex = 0;
  114.         cpb.hFileInfo.ioFlFndrInfo.fdFlags |= 0x4000;    // set invisible flag
  115.         err = PBSetCatInfoSync(&cpb);
  116.     }
  117.  
  118.     // mark that folder uses a custom icon
  119.     cpb.dirInfo.ioVRefNum = vRefNum;
  120.     cpb.dirInfo.ioDrDirID = dirID;
  121.     cpb.dirInfo.ioNamePtr = netFolderName;
  122.     cpb.dirInfo.ioFDirIndex = -1;
  123.     err = PBGetCatInfoSync(&cpb);
  124.     if (err == noErr)
  125.     {
  126.         cpb.dirInfo.ioDrDirID = cpb.dirInfo.ioDrParID;
  127.         cpb.dirInfo.ioNamePtr = netFolderName;
  128.         cpb.dirInfo.ioFDirIndex = 0;
  129.         cpb.hFileInfo.ioFlFndrInfo.fdFlags |= 0x0400;    // set custom icon flag
  130.         err = PBSetCatInfoSync(&cpb);
  131.     }
  132.  
  133. }
  134.  
  135.  
  136. ////////////////////////////////////////////////////////////
  137. //
  138. // Create "The Network" folder if it does not exist.
  139. // Initializes globals->theNetworkVRefNum and globals->theNetworkFolderID
  140. //
  141. OSErr CreateTheNetworkFolder(void)
  142. {
  143.     FSSpec        theNetworkFolder;
  144.     OSErr        err;
  145.     CInfoPBRec    cpb;
  146.     Globals*    globals = GetGlobals();
  147.     
  148.     err = FindFolder(kOnSystemDisk, kDesktopFolderType, kDontCreateFolder, &theNetworkFolder.vRefNum, &theNetworkFolder.parID);
  149.     if (err) return err;
  150.     
  151.     globals->theNetworkVRefNum = theNetworkFolder.vRefNum;
  152.     BlockMove("\pThe Network", &theNetworkFolder.name, 12);
  153.     cpb.dirInfo.ioVRefNum = theNetworkFolder.vRefNum;
  154.     cpb.dirInfo.ioDrDirID = theNetworkFolder.parID;
  155.     cpb.dirInfo.ioNamePtr = (StringPtr)&theNetworkFolder.name;
  156.     cpb.dirInfo.ioFDirIndex = 0;
  157.     cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  158.     err = PBGetCatInfoSync(&cpb);
  159.     
  160.     if (err == noErr)
  161.         globals->theNetworkFolderID = cpb.dirInfo.ioDrDirID;
  162.     else if (err == fnfErr)
  163.     {
  164.         err = FSpDirCreate(&theNetworkFolder, -1, &globals->theNetworkFolderID);
  165.         if (err == noErr)
  166.         {
  167.             SetCustomFolderIcon(globals->theNetworkVRefNum,globals->theNetworkFolderID, 128); 
  168.         }
  169.     }
  170.         
  171.     return err;
  172. }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179. ////////////////////////////////////////////////////////////
  180. //
  181. // Make sure there is a folder in <vRefNum,parID> with name folderName
  182. //
  183. OSErr SyncFolder(short vRefNum, long parID, const char* folderName, long* folderDirID)
  184. {
  185.     CInfoPBRec    cpb;
  186.     OSErr        err;
  187.     
  188.     // see if folder exists
  189.     cpb.dirInfo.ioVRefNum = vRefNum;
  190.     cpb.dirInfo.ioDrDirID = parID;
  191.     cpb.dirInfo.ioNamePtr = (StringPtr)folderName;
  192.     cpb.dirInfo.ioFDirIndex = 0;
  193.     cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  194.     err = PBGetCatInfoSync(&cpb);
  195.     *folderDirID = cpb.dirInfo.ioDrDirID;
  196.     
  197.     if (err == fnfErr)
  198.     {
  199.         HParamBlockRec hpb;
  200.         
  201.         // create a folder aZoneName
  202.         hpb.fileParam.ioVRefNum = vRefNum;
  203.         hpb.fileParam.ioNamePtr = (StringPtr)folderName;
  204.         hpb.fileParam.ioDirID = parID;
  205.         err = PBDirCreateSync(&hpb);
  206.         if ( err == noErr )
  207.         {
  208.             *folderDirID = hpb.fileParam.ioDirID;    // get return result
  209.         
  210.             // set special bit in folder info
  211.             cpb.dirInfo.ioVRefNum = vRefNum;
  212.             cpb.dirInfo.ioDrDirID = parID;
  213.             cpb.dirInfo.ioNamePtr = (StringPtr)folderName;
  214.             cpb.dirInfo.ioFDirIndex = 0;
  215.             cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  216.             err = PBGetCatInfoSync(&cpb);
  217.             if ( err == noErr )
  218.             {
  219.                 cpb.dirInfo.ioVRefNum = vRefNum;
  220.                 cpb.dirInfo.ioDrDirID = parID;
  221.                 cpb.dirInfo.ioNamePtr = (StringPtr)folderName;
  222.                 cpb.dirInfo.ioFDirIndex = 0;
  223.                 cpb.dirInfo.ioDrFndrInfo.frXFlags |= 1;        // this bit lets us know it is our folder
  224.                 cpb.dirInfo.ioDrUsrWds.frView = 0x0200;        // set view by name as default
  225.                 err = PBSetCatInfoSync(&cpb);
  226.             };
  227.         };
  228.     };
  229.     return err;
  230. }
  231.  
  232.  
  233. ////////////////////////////////////////////////////////////
  234. //
  235. // Make sure there is a folder for every zone name
  236. //
  237. void CreateZoneFolders(void)
  238. {
  239. #define kGetZoneListBufferSize    578
  240.     Globals*        globals = GetGlobals();
  241.     char            theZoneList[kGetZoneListBufferSize];
  242.     OSErr            err;
  243.     XCallParam         pb;
  244.     int                theZoneListCount = 0;
  245.         
  246.     // get zone list from a bridge
  247.     pb.xppTimeout = 2;
  248.     pb.xppRetry = 4;
  249.     pb.zipBuffPtr = (Ptr)&theZoneList;
  250.     pb.zipLastFlag = 0;
  251.     pb.zipInfoField[0] = 0;
  252.     pb.zipInfoField[1] = 0;
  253.     while ( pb.zipLastFlag == 0 )
  254.     {
  255.         // get each chunk of zone list
  256.         err = GetZoneListSync((XPPParmBlkPtr)&pb);
  257.         
  258.         if ( err != noErr ) break;
  259.         
  260.         // offset zipBuffPtr to end of this list
  261.         {
  262.             long        tempDirID;
  263.             char*         s = pb.zipBuffPtr;
  264.             
  265.             // make sure there is a folder for each zone
  266.             while ( pb.zipNumZones-- > 0 )
  267.             {
  268.                 SyncFolder(globals->theNetworkVRefNum, globals->theNetworkFolderID, s, &tempDirID);
  269.                 
  270.                 s += *s;
  271.                 s++;
  272.                 theZoneListCount++;
  273.             }
  274.         }
  275.     }
  276.     
  277. }
  278.  
  279.  
  280. ////////////////////////////////////////////////////////////
  281. //
  282. // For every afp server in a zone, make sure there is a folder.
  283. //
  284. void SyncServersInAZone(const char* zoneName)
  285. {
  286.     EntityName                searchCriteria;    
  287.     char                    buffer[1000];
  288.     OSErr                    err;
  289.     NBPparms                mpb;
  290.     Globals*                globals = GetGlobals();
  291.  
  292.     // pack entity names
  293.     NBPSetEntity((Ptr)&searchCriteria, (Ptr)"\p=", (Ptr)"\pAFPServer", (Ptr)zoneName);
  294.     
  295.     // Do a NBP Lookup 
  296.     mpb.interval                 = 8;
  297.     mpb.count                     = 4;
  298.     mpb.NBPPtrs.entityPtr         = (Ptr)&searchCriteria;
  299.     mpb.parm.Lookup.retBuffPtr     = buffer;
  300.     mpb.parm.Lookup.retBuffSize = 1000;
  301.     mpb.parm.Lookup.maxToGet     = 100;
  302.     err = PLookupNameSync((MPPPBPtr)&mpb);
  303.     
  304.     if (err == noErr)
  305.     {
  306.         short        serverCount = mpb.parm.Lookup.numGotten;
  307.         long        zoneFolderID;
  308.         int            i;
  309.         
  310.         // make sure there is a zone folder for this zone
  311.         SyncFolder(globals->theNetworkVRefNum, globals->theNetworkFolderID, zoneName, &zoneFolderID);
  312.     
  313.         // for each server found by NBP
  314.         for (i = 1; i <= serverCount; i++)
  315.         {
  316.             AddrBlock    address;
  317.             EntityName    aServer;    
  318.             long        temp;
  319.             
  320.             // make sure there is a server folder for this server
  321.             err = NBPExtract(buffer, serverCount, i, &aServer, &address);
  322.             if (err == noErr)
  323.                 SyncFolder(globals->theNetworkVRefNum, zoneFolderID, (const char*)aServer.objStr, &temp);
  324.         }
  325.  
  326.     }
  327. }
  328.  
  329.  
  330. ////////////////////////////////////////////////////////////
  331. //
  332. // Given a zone and server name, find its network address
  333. //
  334. OSErr GetFileServerAddress (const char* zoneName, const char* serverName, AddrBlock* serverAddr)  
  335. {
  336.     EntityName                searchCriteria;    
  337.     char                    buffer[120];
  338.     OSErr                    err;
  339.     NBPparms                mpb;
  340.  
  341.     // pack entity names
  342.     NBPSetEntity((Ptr)&searchCriteria, (Ptr)serverName, (Ptr)"\pAFPServer", (Ptr)zoneName);
  343.     
  344.     // Do a NBP Lookup 
  345.     mpb.interval                 = 8;    // allow 8 ticks before looking again
  346.     mpb.count                     = 2;    // allow up to 2 retries
  347.     mpb.NBPPtrs.entityPtr         = (Ptr)&searchCriteria;
  348.     mpb.parm.Lookup.retBuffPtr     = buffer;
  349.     mpb.parm.Lookup.retBuffSize = 120;
  350.     mpb.parm.Lookup.maxToGet     = 1;    // just looking for 1 thing
  351.     err = PLookupNameSync((MPPPBPtr)&mpb);
  352.     
  353.     if ( (err == noErr) && (mpb.parm.Lookup.numGotten == 1) )
  354.     {
  355.         EntityName    aServer;    
  356.         
  357.         // make sure there is a server folder for this server
  358.         err = NBPExtract(buffer, 1, 1, &aServer, serverAddr);
  359.     }
  360.     return err;
  361. }
  362.  
  363. typedef struct {
  364.     short machineTypeOffset;
  365.     short AFPversOffset;
  366.     short UAMStringsOffset;
  367.     short iconMaskOffset;
  368.     short flags;
  369.     Str31 serverName;
  370.     Str15 machineType;
  371.     char  variableData[128+256];
  372. } ASPGetStatusReplyBuf;
  373.  
  374.  
  375.  
  376. ////////////////////////////////////////////////////////////
  377. //
  378. // Given a server address, figures out if it support guest login
  379. //
  380. Boolean FileServerAllowsGuests (AddrBlock serverAddr)
  381. {
  382.     XPPPrmBlk             pb;        // param block for ASPGetStatus call
  383.      ASPGetStatusReplyBuf buffer;    // reply buffer for ASPGetStatus call
  384.  
  385.     pb.ioRefNum     = xppRefNum;
  386.     pb.aspTimeout    = 1;             // allow 8 ticks before getting server info again
  387.     pb.aspRetry     = 2;             // allow 2 max retries
  388.     *(AddrBlock *)(&pb.cbSize) = serverAddr; // need to stuff AddrBlock at this offset in pb
  389.     pb.rbSize         = sizeof(ASPGetStatusReplyBuf);
  390.     pb.rbPtr         = (Ptr)&buffer;
  391.         
  392.     if (ASPGetStatusSync((XPPParmBlkPtr)&pb) == noErr) 
  393.     {
  394.         Ptr             uamStringsPtr;        // pointer into UAM strings
  395.         unsigned char    countOfUAMStrings;    // count of UAM strings
  396.         int                i;
  397.         
  398.         uamStringsPtr = ((Ptr)&buffer) + buffer.UAMStringsOffset;
  399.         countOfUAMStrings = *uamStringsPtr++;    // first byte is count of number of UAM strings 
  400.         
  401.         // look for "No User Authent" in list
  402.         for (i=1; i <= countOfUAMStrings; ++i)
  403.         {
  404.             if (EqualString("\pNo User Authent", (StringPtr)uamStringsPtr, false, true))
  405.                 return true;
  406.             else
  407.                 uamStringsPtr += (Length(uamStringsPtr) +1); // point to the next UAM string
  408.         }
  409.         
  410.         // guest login not allowed (could not find "No User Authent" in list)
  411.         return false;        
  412.     }
  413.     
  414.  
  415.  
  416. ////////////////////////////////////////////////////////////
  417. //
  418. // Given a server name and zone name, find coresponding folder dirID
  419. //
  420. OSErr GetServerFolderID(const char* zoneName, const char* serverName, long* serverDirID)
  421. {
  422.     long         zoneDirID;
  423.     OSErr        err;
  424.     Globals*    globals = GetGlobals();
  425.     
  426.     err = SyncFolder(globals->theNetworkVRefNum, globals->theNetworkFolderID, zoneName, &zoneDirID);
  427.     if ( err == noErr )
  428.         err = SyncFolder(globals->theNetworkVRefNum, zoneDirID, serverName, serverDirID);
  429.         
  430.     return err;
  431. }
  432.  
  433.             
  434. ////////////////////////////////////////////////////////////
  435. //
  436. // Given a server address, figures out if it support guest login
  437. //
  438. OSErr CreateVolumeAlias(short serverVRefNum, long serverDirID, const char* volumeName)
  439. {
  440.     CInfoPBRec    cpb;
  441.     OSErr        err;
  442.     
  443.     // see if alias exists
  444.     cpb.hFileInfo.ioVRefNum = serverVRefNum;
  445.     cpb.hFileInfo.ioDirID     = serverDirID;
  446.     cpb.hFileInfo.ioNamePtr = (StringPtr)volumeName;
  447.     cpb.hFileInfo.ioFDirIndex = 0;
  448.     cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  449.     err = PBGetCatInfoSync(&cpb);    
  450.     if (err == fnfErr)
  451.     {
  452.         HParamBlockRec hpb;
  453.         
  454.         // create an alias file volumeName
  455.         hpb.fileParam.ioVRefNum = serverVRefNum;
  456.         hpb.fileParam.ioNamePtr = (StringPtr)volumeName;
  457.         hpb.fileParam.ioFlVersNum = 0;
  458.         hpb.fileParam.ioDirID = serverDirID;
  459.         err = PBHCreateSync(&hpb);
  460.         if (err != noErr)
  461.             return err;
  462.     
  463.         // get info about it
  464.         cpb.hFileInfo.ioVRefNum = serverVRefNum;
  465.         cpb.hFileInfo.ioDirID     = serverDirID;
  466.         cpb.hFileInfo.ioNamePtr = (StringPtr)volumeName;
  467.         cpb.hFileInfo.ioFDirIndex = 0;
  468.         cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  469.         err = PBGetCatInfoSync(&cpb);
  470.         
  471.         // set type and creator
  472.         cpb.hFileInfo.ioFlFndrInfo.fdType = 'fdrp';        // should be 'srvr' but Finder wants those to have custom icons
  473.         cpb.hFileInfo.ioFlFndrInfo.fdCreator = 'MACS';
  474.         cpb.hFileInfo.ioFlFndrInfo.fdFlags |= 0x8000;        // flip on alias bit
  475.         
  476.         // set new info
  477.         cpb.hFileInfo.ioVRefNum = serverVRefNum;
  478.         cpb.hFileInfo.ioDirID     = serverDirID;
  479.         cpb.hFileInfo.ioNamePtr = (StringPtr)volumeName;
  480.         cpb.hFileInfo.ioFDirIndex = 0;
  481.         err = PBSetCatInfoSync(&cpb);
  482.     }
  483.     
  484.     return err;
  485. }
  486.  
  487.  
  488.  
  489. ////////////////////////////////////////////////////////////
  490. //
  491. // Given a server, make sure there is a volume alias for each volume
  492. //
  493. OSErr SyncVolumesInAServer(const char* zoneName, const char* serverName)
  494. {
  495.     AddrBlock    serverAddr;
  496.     OSErr        err;
  497.     Globals*    globals = GetGlobals();
  498.     
  499.     if ( ((err=GetFileServerAddress (zoneName, serverName, &serverAddr))  == noErr) && FileServerAllowsGuests(serverAddr) )
  500.     {
  501.         // log on to AFP server to get volume info
  502.         char                scb[scbMemSize];    // session control block 
  503.         char                command[32];
  504.         AFPLoginPrm             loginPB;
  505.         char                replyBuffer[100];                    
  506.         
  507.         command[0] = afpLogin;
  508.         BlockMove("\pAFPVersion 2.1", (void*)&command[1], 15);
  509.         BlockMove("\pNo User Authent", (void*)&command[16], 16);
  510.         
  511.         loginPB.ioRefNum     = xppRefNum;
  512.         loginPB.aspTimeout    = 1;             // allow 8 ticks before getting server info again
  513.         loginPB.aspRetry     = 2;             // allow 2 max retries
  514.         loginPB.afpAddrBlock= serverAddr;     
  515.         loginPB.cbSize         = 32;
  516.         loginPB.cbPtr         = (Ptr)&command;
  517.         loginPB.rbSize         = 100;
  518.         loginPB.rbPtr         = replyBuffer;
  519.         loginPB.afpSCBPtr    = (Ptr)&scb;    // control block for use during session
  520.         loginPB.afpAttnRoutine    = NULL;
  521.         AFPCommandSync((XPPParmBlkPtr)&loginPB);
  522.         err = (loginPB.ioResult ? loginPB.ioResult : loginPB.cmdResult);
  523.         if ( err == noErr )
  524.         {
  525.              // use AFPGetSrvrParms to get list of volume names
  526.             char        commandBuffer[2];
  527.             char        replyBuffer[1000];
  528.             XPPPrmBlk    infoPB;                    
  529.             
  530.             commandBuffer[0]     = afpGetSParms;
  531.             infoPB.ioRefNum     = xppRefNum;
  532.             infoPB.sessRefnum    = loginPB.sessRefnum;
  533.             infoPB.cbSize         = 1;
  534.             infoPB.cbPtr         = commandBuffer;
  535.             infoPB.rbSize         = 1000;
  536.             infoPB.rbPtr         = replyBuffer;
  537.             AFPCommandSync((XPPParmBlkPtr)&infoPB);
  538.             err = (infoPB.ioResult ? infoPB.ioResult : infoPB.cmdResult);
  539.             if ( err == noErr )
  540.             {
  541.                 char* s = &replyBuffer[4];    // skip over server time header
  542.                 int numVols = *s++;            // get number of volumes
  543.                 int    i;
  544.                 long serverDirID;
  545.                 
  546.                 err = GetServerFolderID(zoneName, serverName, &serverDirID);
  547.                 if ( err == noErr )
  548.                 {
  549.                     for ( i = 0; i < numVols; ++i)
  550.                     {
  551.                         s++;    // skip volume attributes byte
  552.                         CreateVolumeAlias(globals->theNetworkVRefNum, serverDirID, s);
  553.                         s += (Length(s) + 1);
  554.                     }
  555.                 }
  556.              }
  557.              
  558.              // logout from server 
  559.             command[0]            = afpLogout;
  560.             loginPB.ioRefNum     = xppRefNum;
  561.             loginPB.cbSize         = 1;
  562.             loginPB.cbPtr         = (Ptr)&command;
  563.              AFPCommandSync((XPPParmBlkPtr)&loginPB);
  564.          }        
  565.     }
  566.     return err;
  567. }
  568.  
  569.  
  570. ////////////////////////////////////////////////////////////
  571. //
  572. // Given a folder vRefNum and dirID, return its name and parent folder dirID
  573. //
  574. OSErr GetFolderName(short vRefNum, long folderID, char* folderName, long* parID)
  575. {
  576.     CInfoPBRec    cpb;
  577.     OSErr        err;
  578.     
  579.     cpb.dirInfo.ioVRefNum = vRefNum;
  580.     cpb.dirInfo.ioDrDirID = folderID;
  581.     cpb.dirInfo.ioNamePtr = (StringPtr)folderName;
  582.     cpb.dirInfo.ioFDirIndex = -1;
  583.     cpb.hFileInfo.ioFlFndrInfo.fdType = 'nick';        // flag to avoid recursion
  584.     err = PBGetCatInfoSync(&cpb);
  585.     *parID = cpb.dirInfo.ioDrParID;
  586.     return err;
  587. }
  588.  
  589.             
  590. ////////////////////////////////////////////////////////////
  591. //
  592. // Make sure the contents of a special folder is in sync with what is on the network.
  593. //
  594. pascal void SyncSpecialFolder(short vRefNum, long parentFolderID, const unsigned char* folderName)
  595. {
  596.     Globals*    globals = GetGlobals();
  597.     
  598.     if ( vRefNum == globals->theNetworkVRefNum )
  599.     {    
  600.         if ( parentFolderID == globals->theNetworkFolderID )
  601.         {
  602.             // this is a zone folder that needs to be synced
  603.             SyncServersInAZone(folderName);
  604.         }
  605.         else
  606.         {
  607.             // must be a server folder
  608.             char    zoneName[32];
  609.             long    temp;
  610.             
  611.             // get zone name it is in and sync it
  612.             if ( GetFolderName(vRefNum, parentFolderID, &zoneName[0], &temp) == noErr )
  613.                 SyncVolumesInAServer(zoneName, folderName);
  614.         }
  615.     }
  616. }
  617.  
  618.  
  619.  
  620. ////////////////////////////////////////////////////////////
  621. //
  622. // When the user tries to use an empty alias, this is called
  623. // to mount the volume and fill in the alias file.
  624. //
  625. pascal short OpenVolumeAliasFile(short vRefNum, long serverFolderID, const unsigned char* volumeName)
  626. {
  627.     Globals*    globals = GetGlobals();
  628.     
  629.     if ( vRefNum == globals->theNetworkVRefNum )
  630.     {    
  631.         AFPVolMountInfo        mountInfo;
  632.         ParamBlockRec        pb;
  633.         long                zoneFolderID;
  634.         long                netFolderID;
  635.         
  636.         if (( GetFolderName(vRefNum, serverFolderID, &mountInfo.AFPData[32], &zoneFolderID) == noErr )     // get servername
  637.             && ( GetFolderName(vRefNum, zoneFolderID, &mountInfo.AFPData[0], &netFolderID) == noErr )     // get zonename
  638.             && ( netFolderID = globals->theNetworkFolderID ) )
  639.         {
  640.             BlockMove(volumeName, &mountInfo.AFPData[64], 32);
  641.             mountInfo.length         = sizeof(AFPVolMountInfo);
  642.             mountInfo.media         = AppleShareMediaType;
  643.             mountInfo.flags         = 0;
  644.             mountInfo.nbpInterval     = 0;
  645.             mountInfo.nbpCount         = 0;
  646.             mountInfo.uamType         = kNoUserAuthentication;
  647.             mountInfo.zoneNameOffset         = offsetof(AFPVolMountInfo, AFPData);
  648.             mountInfo.serverNameOffset         = offsetof(AFPVolMountInfo, AFPData[32]);
  649.             mountInfo.volNameOffset         = offsetof(AFPVolMountInfo, AFPData[64]);
  650.             mountInfo.userNameOffset         = offsetof(AFPVolMountInfo, AFPData[96]);
  651.             mountInfo.userPasswordOffset     = offsetof(AFPVolMountInfo, AFPData[96]);
  652.             mountInfo.volPasswordOffset        = offsetof(AFPVolMountInfo, AFPData[96]);
  653.             mountInfo.AFPData[96] = 0;
  654.                     
  655.             pb.ioParam.ioBuffer = (Ptr)&mountInfo;
  656.             if ( PBMountAFPVolSync(&pb) == noErr )
  657.             {
  658.                 FSSpec        newVolume;
  659.                                 
  660.                 // make FSSpec for volume
  661.                 newVolume.vRefNum = pb.ioParam.ioVRefNum;
  662.                 newVolume.parID = 1;
  663.                 pb.volumeParam.ioVolIndex = -1;
  664.                 pb.volumeParam.ioNamePtr = newVolume.name;
  665.                 if ( PBGetVInfoSync(&pb) == noErr )
  666.                 {
  667.                     AliasHandle    h;
  668.                     short        ref;
  669.                     
  670.                     // make alias to the volume
  671.                     if ( NewAliasMinimal(&newVolume, &h) == noErr )
  672.                     {
  673.                         HCreateResFile(vRefNum, serverFolderID, volumeName);
  674.                         ref = HOpenResFile(vRefNum, serverFolderID, volumeName, fsCurPerm); 
  675.                         if ( ref != -1 )
  676.                             AddResource( (Handle)h, 'alis', 0, volumeName);
  677.                         else
  678.                             DisposeHandle((Handle)h);
  679.  
  680.                         return ref;
  681.                     }
  682.                 }
  683.             }    
  684.         }
  685.  
  686.         return -1;
  687.     }
  688. }
  689.  
  690.  
  691. void DoInstall()
  692. {
  693.     Debugger();
  694.     CreateTheNetworkFolder();
  695.     
  696.     CreateZoneFolders();
  697.     
  698.     InstallPatches();    
  699. }
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.